package club.bigtian.statusbar;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Token刷新服务
 * 使用hutool实现并发刷新账户信息
 */
public class TokenRefreshService {

    // 线程池，用于并发刷新
    private static final ExecutorService executor = Executors.newFixedThreadPool(10);

    /**
     * Portal信息
     */
    @Data
    public static class PortalInfo {
        private Integer creditsBalance;
        private String expiryDate;
        private Boolean canStillUse;
    }

    /**
     * 刷新结果
     */
    @Data
    public static class RefreshResult {
        private String id;
        private String tenantUrl;
        private String emailNote;
        private String banStatus;
        private PortalInfo portalInfo;
        private String errorMessage;
        private boolean success;
    }

    /**
     * 批量并发刷新所有账户
     */
    public static List<RefreshResult> batchRefreshAccounts(List<TokenConfig.TokenRawData> tokens) {
        System.out.println("🔄 开始批量刷新 " + tokens.size() + " 个账户...");
        
        List<CompletableFuture<RefreshResult>> futures = new ArrayList<>();

        // 为每个token创建异步任务
        for (TokenConfig.TokenRawData token : tokens) {
            CompletableFuture<RefreshResult> future = CompletableFuture.supplyAsync(() -> {
                return refreshSingleAccount(token);
            }, executor);
            futures.add(future);
        }

        // 等待所有任务完成
        List<RefreshResult> results = new ArrayList<>();
        for (CompletableFuture<RefreshResult> future : futures) {
            try {
                RefreshResult result = future.get(30, TimeUnit.SECONDS);
                results.add(result);
            } catch (Exception e) {
                System.err.println("❌ 刷新任务失败: " + e.getMessage());
                RefreshResult errorResult = new RefreshResult();
                errorResult.setSuccess(false);
                errorResult.setErrorMessage("刷新超时或失败: " + e.getMessage());
                results.add(errorResult);
            }
        }

        System.out.println("✅ 批量刷新完成，成功: " + results.stream().filter(RefreshResult::isSuccess).count() + 
                         "/" + results.size());
        return results;
    }

    /**
     * 刷新单个账户
     */
    private static RefreshResult refreshSingleAccount(TokenConfig.TokenRawData token) {
        RefreshResult result = new RefreshResult();
        result.setId(token.getId());
        result.setTenantUrl(token.getTenantUrl());
        result.setEmailNote(token.getEmailNote());

        try {
            System.out.println("🔍 刷新账户: " + token.getEmailNote());

            // 1. 检查账号状态
            String banStatus = checkAccountStatus(token.getAccessToken(), token.getTenantUrl());
            result.setBanStatus(banStatus);

            // 2. 如果账号正常，获取Portal信息
            if ("ACTIVE".equals(banStatus)) {
                PortalInfo portalInfo = getPortalInfo(token);
                result.setPortalInfo(portalInfo);
                result.setSuccess(true);
                System.out.println("  ✅ " + token.getEmailNote() + " - 余额: " +
                                 (portalInfo != null ? portalInfo.getCreditsBalance() : "N/A"));
            } else if (banStatus != null && banStatus.startsWith("ERROR")) {
                // 检查失败（网络错误、超时等），不更新状态，避免误判
                result.setSuccess(false);
                result.setErrorMessage("检查状态失败: " + banStatus);
                System.out.println("  ❌ " + token.getEmailNote() + " - 检查失败: " + banStatus + "（不更新状态）");
            } else {
                // 明确的非正常状态（BANNED、INVALID_TOKEN、FORBIDDEN等）
                result.setSuccess(true);
                result.setErrorMessage("账号状态: " + banStatus);
                System.out.println("  ⚠️ " + token.getEmailNote() + " - 状态: " + banStatus);
            }

        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorMessage("刷新失败: " + e.getMessage());
            System.err.println("  ❌ " + token.getEmailNote() + " - 错误: " + e.getMessage());
        }

        return result;
    }

    /**
     * 检查账号状态
     */
    private static String checkAccountStatus(String accessToken, String tenantUrl) {
        try {
            String url = tenantUrl.replaceAll("/$", "") + "/find-missing";
            
            HttpResponse response = HttpRequest.post(url)
                    .header("Authorization", "Bearer " + accessToken)
                    .header("Content-Type", "application/json")
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .body("{}")
                    .timeout(10000)
                    .execute();

            int statusCode = response.getStatus();
            String body = response.body();

            // 根据状态码判断账号状态
            if (statusCode == 200) {
                return "ACTIVE";
            } else if (statusCode == 401) {
                return "INVALID_TOKEN";
            } else if (statusCode == 403) {
                // 检查是否是封禁
                if (body != null && body.contains("banned")) {
                    return "BANNED";
                }
                return "FORBIDDEN";
            } else if (statusCode == 404) {
                return "NOT_FOUND";
            } else {
                return "ERROR_" + statusCode;
            }

        } catch (Exception e) {
            System.err.println("检查账号状态失败: " + e.getMessage());
            return "ERROR";
        }
    }

    /**
     * 获取Portal信息
     */
    private static PortalInfo getPortalInfo(TokenConfig.TokenRawData token) {
        try {
            // 从tenant_url提取portal token
            // 假设portal URL格式: https://portal.withorb.com/?token=xxx
            String portalToken = extractPortalToken(token);
            if (portalToken == null || portalToken.isEmpty()) {
                System.out.println("  ⚠️ 无法提取Portal Token");
                return null;
            }

            // 1. 获取customer信息
            String customerUrl = "https://portal.withorb.com/api/v1/customer_from_link?token=" + portalToken;
            
            HttpResponse customerResponse = HttpRequest.get(customerUrl)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .header("Accept", "application/json, text/plain, */*")
                    .header("Accept-Language", "en-US,en;q=0.9")
                    .timeout(10000)
                    .execute();

            if (!customerResponse.isOk()) {
                System.out.println("  ⚠️ 获取Customer信息失败: " + customerResponse.getStatus());
                return null;
            }

            JSONObject customerData = JSONUtil.parseObj(customerResponse.body());
            JSONObject customer = customerData.getJSONObject("customer");
            
            String customerId = customer.getStr("id");
            String pricingUnitId = customer.getJSONArray("ledger_pricing_units")
                    .getJSONObject(0)
                    .getStr("id");

            // 2. 获取ledger summary
            String ledgerUrl = String.format(
                    "https://portal.withorb.com/api/v1/customers/%s/ledger_summary?pricing_unit_id=%s&token=%s",
                    customerId, pricingUnitId, portalToken
            );

            HttpResponse ledgerResponse = HttpRequest.get(ledgerUrl)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .header("Accept", "application/json, text/plain, */*")
                    .header("Accept-Language", "en-US,en;q=0.9")
                    .timeout(10000)
                    .execute();

            if (!ledgerResponse.isOk()) {
                System.out.println("  ⚠️ 获取Ledger信息失败: " + ledgerResponse.getStatus());
                return null;
            }

            JSONObject ledgerData = JSONUtil.parseObj(ledgerResponse.body());

            // 解析Portal信息
            PortalInfo portalInfo = new PortalInfo();
            
            // credits_balance 可能是字符串或数字
            Object creditsBalanceObj = ledgerData.get("credits_balance");
            if (creditsBalanceObj != null) {
                if (creditsBalanceObj instanceof String) {
                    portalInfo.setCreditsBalance((int) Double.parseDouble((String) creditsBalanceObj));
                } else if (creditsBalanceObj instanceof Number) {
                    portalInfo.setCreditsBalance(((Number) creditsBalanceObj).intValue());
                }
            } else {
                portalInfo.setCreditsBalance(0);
            }

            // 获取过期时间
            if (ledgerData.getJSONArray("credit_blocks") != null && 
                !ledgerData.getJSONArray("credit_blocks").isEmpty()) {
                JSONObject firstBlock = ledgerData.getJSONArray("credit_blocks").getJSONObject(0);
                portalInfo.setExpiryDate(firstBlock.getStr("expiry_date"));
            }

            portalInfo.setCanStillUse(portalInfo.getCreditsBalance() > 0);

            return portalInfo;

        } catch (Exception e) {
            System.err.println("  ❌ 获取Portal信息失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 从token数据中提取portal token
     * portal_url格式: https://portal.withorb.com/?token=xxx
     */
    private static String extractPortalToken(TokenConfig.TokenRawData token) {
        try {
            String portalUrl = token.getPortalUrl();
            if (portalUrl == null || portalUrl.isEmpty()) {
                return null;
            }

            // 从URL中提取token参数
            if (portalUrl.contains("token=")) {
                String[] parts = portalUrl.split("token=");
                if (parts.length > 1) {
                    // 可能还有其他参数，只取token部分
                    String tokenPart = parts[1];
                    int ampIndex = tokenPart.indexOf('&');
                    if (ampIndex > 0) {
                        return tokenPart.substring(0, ampIndex);
                    }
                    return tokenPart;
                }
            }

            return null;
        } catch (Exception e) {
            System.err.println("提取Portal Token失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 关闭线程池
     */
    public static void shutdown() {
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
        }
    }
}

